<?php
class Api_DbTable_Product extends Core_Db_Table_Abstract implements Core_Db_Crud_Interface
{
    const FILES_DIR = '/image/product/';
    protected $_name = 'products';
    protected $_rowClass = 'Api_Row_Product';
    protected $_user = null;
    protected $_api = null;

    public function init()
    {
        $this->_user = Zend_Registry::get('Core_User');
    }

    public function special()
    {
        return $this->fetchAll($this->select()->where('is_special = 1')->limit(5));
    }

    public function lastNew()
    {
        return $this->fetchAll($this->select()->where('is_new = 1')->limit(5)->order('date DESC'));
    }

    public function search($search_str, $filter = Api_Select_Product::FILTER_ALL, $sort = Api_Select_Product::SORT_CODE, $is_asc = true)
    {
        return $this->fetchAll($this->select()->filter($filter)->sort($sort, $is_asc)->search($search_str));
    }

    public function FetchByAuthor( $AuthorId, $filter = Api_Select_Product::FILTER_ALL, $sort = Api_Select_Product::SORT_CODE, $is_asc = true )
    {
        return $this->fetchAll($s = $this->select()->filter($filter)->sort($sort, $is_asc)->author($AuthorId));
    }

    public function select($withFromPart = self::SELECT_WITHOUT_FROM_PART)
    {
        $select = new Api_Select_Product ($this);
        if ($withFromPart == self::SELECT_WITH_FROM_PART)
            $select->from($this->info(self::NAME), Zend_Db_Table_Select::SQL_WILDCARD, $this->info(self::SCHEMA));

        $select->from(array('p' => 'products'))->setIntegrityCheck(false);

        //		if(!$this->_user->isGuest())
        $select->join(array('pr' => 'prices'), '`p`.`id` = `pr`.`product_id`', array('price' => $this->_user->getPriceScheme()))
                ->join(array('a' => 'available'), '`p`.`id` = `a`.`product_id`', array("quantity"))
                ->join(array('ap' => 'author_products'), '`p`.`id` = `ap`.`product_id`', array("author_id"))
                ->join(array('au' => 'authors'), '`ap`.`author_id` = `au`.`id`', array("authors_name"));

        return $select;
    }

    public function find($id, $withImages = false, Zend_Db_Table_Select $select = null)
    {
        if (is_null($select))
            $select = $this->select();

        if (is_array($id)) {
            $select->where('`p`.`id` in ' . '(' . implode(',', $id) . ')');

            return $this->fetchAll($select);
        }
        if (is_int($id)) {
            $select->where('`p`.`id` = ?', ( int )$id);
            $row = $this->fetchRow($select);
            if ($withImages)
                $row->setImages($this->_api->Image->all($id));
            return $row;
        }

        return null;
    }

    private function setPrice($data)
    {
        $db = Zend_Db_Table_Abstract::getDefaultAdapter()->getConnection();
        $sql = "INSERT INTO `prices` (`product_id`, `price_1`, `price_2`) VALUES('" . $data ['product_id'] . "',
			'" . $data ['price_1'] . "', '" . $data ['price_2'] . "');";

        $db->exec($sql);
    }

    private function setAvailable($data)
    {
        $db = Zend_Db_Table_Abstract::getDefaultAdapter()->getConnection();
        $sql = "INSERT INTO `available` (`product_id`, `quantity`) VALUES('" . $data ['product_id'] . "',
			'" . $data ['quantity'] . "');";
        $db->exec($sql);
    }

    public function insert($data)
    {

        $p1 = $data ["price_1"];
        unset ($data ["price_1"]);

        $p2 = $data ["price_2"];
        unset ($data ["price_2"]);

        $quantity = $data ["quantity"];
        unset ($data ["quantity"]);

        unset ($data ['id']);
        $prod_id = parent::insert($data);

        $prices = array("product_id" => $prod_id, "price_1" => $p1, "price_2" => $p2);
        $aval = array("product_id" => $prod_id, "quantity" => $quantity);

        $this->setPrice($prices);
        $this->setAvailable($aval);

    }

    public function getFromCategory(Api_Row_Category $category, $filter = null, $sort = null, $is_asc = true)
    {
        $select = $this->select();
        if (!is_null($filter))
            $select->filter($filter);
        if (!is_null($sort))
            $select->sort($sort, $is_asc);
        return $this->fetchAll($select->where('`p`.`parent_id` = ?', $category->id));
    }

    protected function _newName()
    {
        list ($usec, $sec) = explode(' ', microtime());
        mt_srand(( float )$sec + (( float )$usec * 100000));
        while (file_exists(self::FILES_DIR . ($name = md5(mt_rand())) . '.jpg')) {
        }
        return $name;
    }

    protected function _saveImgs($path, $name)
    {
        $prePath = APPLICATION_PATH . '/../public' . self::FILES_DIR;
        foreach (array(170, 45) as $size) {
            $img = new Core_Image ($path, 100);
            $img->resize(( int )$size, ( int )$size);
            $file = $prePath . ( string )$size . '/' . $name . '.jpg';
            if (file_exists($file))
                unlink($file);
            $img->save($file);
            unset ($img);
        }
    }

    public function setManager(Application_Model_Manager $manager)
    {
        $this->_api = $manager;
    }

    public function getManager()
    {
        return $this->_api;
    }

    public function getAll($parent = null)
    {
        $select = new Api_Select_Product ($this);
        return $this->fetchAll($select->all()->where('p.parent_id = ?', ( int )$parent));
    }

    public function getIds($ids)
    {
        if (!isset ($ids))
            return null;
        $select = new Api_Select_Product ($this);
        foreach ($ids as $id)
            $products [] = $this->fetchAll($select->all()->where('p.id = ?', $id));
        return $products;
    }

    public function getBackUrl($id, $type = 0)
    {
        $id = ( int )$id;
        switch ($type) {
            case 0 :
                $parent_id = $this->_api->Category->find($id)->parent_id;
                break;
            case 3 :
            case 1 :
                $parent_id = $id;
                break;
            case 2 :
                $parent_id = $this->find($id)->parent_id;
                break;
        }

        return Zend_Controller_Front::getInstance()->getRouter()->assemble(array("controller" => "admin", "action" => "read", "name" => $type === 0
                                                                                                           ? "category"
                                        : "product", "id" => $parent_id), null, true);
    }

    public function getForm($id, $req = true)
    {
        return new Api_Form_Product (null, $req);
    }

    public function create(Zend_Form $form, $parent = 0)
    {

        $name = $this->_newName();
        $this->_saveImgs($_FILES ['img_src'] ['tmp_name'], $name);

        $data = $form->getValues();
        $data ['img_src'] = $name;
        $data ['parent_id'] = $parent;

        if (isset ($data ['date'])) {
            $zd = new Zend_Date ($data ['date']);
            $data ['date'] = $zd->getTimestamp();
        } else
            $data ['date'] = time();

        $this->insert($data);
    }

    public function _deleteFiles($src)
    {
        $prePath = APPLICATION_PATH . '/../public' . self::FILES_DIR;
        foreach (array(170, 45) as $size) {
            $file = $prePath . ( string )$size . '/' . $src . '.jpg';
            if (file_exists($file))
                unlink($file);
        }
    }

    public function getMetaData($id)
    {
        return array("image", "code", "title", "in pack", "meter", "price 1", "price 2", " ", " ", " ");
    }

    private function updateSql($table, $data, $id)
    {
        $db = Zend_Db_Table_Abstract::getDefaultAdapter()->getConnection();
        $sql = "UPDATE `" . $table . "` SET ";
        $start = true;
        foreach ($data as $key => $val) {
            if ($start)
                $start = false;
            else
                $sql .= ", ";
            $sql .= "`" . $key . "`=" . $val;
        }
        $sql .= " WHERE `product_id`=" . $id;
        $db->exec($sql);
    }

    public function update($data, $id)
    {
        $id = ( int )$id;

        $prices = array();
        if (isset ($data ['price_1'])) {
            $prices ["price_1"] = $data ['price_1'];
            unset ($data ['price_1']);
        }
        if (isset ($data ['price_2'])) {
            $prices ["price_2"] = $data ['price_2'];
            unset ($data ['price_2']);
        }
        $quantity = array();
        if (isset ($data ['quantity'])) {
            $quantity ["quantity"] = $data ['quantity'];
            unset ($data ['quantity']);
        }

        if (count($prices) > 0)
            $this->updateSql('prices', $prices, $id);
        if (count($quantity) > 0)
            $this->updateSql('available', $quantity, $id);
        parent::update($data, "id = " . $id);

    }

    public function getOne($id)
    {
        $select = new Api_Select_Product ($this);
        $r = $this->fetchRow($select->all()->where('p.id = ?', ( int )$id));
        $zd = new Zend_Date ($r ['date']);
        $r ['date'] = $zd->toString('MM/dd/yyyy');
        return $r;
    }

    public function edit(Zend_Form $form, $id)
    {
        $src = $this->find($id)->img_src;
        $file = $_FILES ['img_src'] ['tmp_name'];
        if (file_exists($file))
            $this->_saveImgs($_FILES ['img_src'] ['tmp_name'], $src);

        $data = $form->getValues();
        if (isset ($data ['date'])) {
            $zd = new Zend_Date ($data ['date']);
            $data ['date'] = $zd->getTimestamp();
        }
        unset ($data ['img_src'], $data ['parent_id']);

        $this->update($data, $id);
    }

    private function deleteSql($table, $id)
    {
        $db = Zend_Db_Table_Abstract::getDefaultAdapter()->getConnection();
        $sql = "DELETE FROM `" . $table . "` ";
        $sql .= "WHERE `product_id`=" . $id;
        $db->exec($sql);
    }

    public function remove($id)
    {
        $src = $this->find($id)->img_src;
        $this->_deleteFiles($src);
        $this->deleteSql('prices', $id);
        $this->deleteSql('available', $id);
        parent::delete("id = " . $id);
    }
}